在开发工作中,通常写好代码后我们都会先自测一遍再交给测试部门,自测的方法有多种,也有多种测试工具,比如Postman、Jmeter等,这篇文章主要讲对于SpringBoot项目如何使用SpringBoot的单元测试,使用的SpringBoot版本是1.5.7。
一.示例项目介绍
创建一个SpringBoot的Maven项目,我的项目结构为:
SpringBoot的单元测试需要额外添加的依赖是:
1 | <dependency> |
下面给出项目的代码部分。
Javabean类:Book.java
1 | package com.lzumetal.springboot.demodatabase.entity; |
dao类:BookMapper.java
1 | package com.lzumetal.springboot.demodatabase.mapper; |
对应的xml映射文件:BookMapper.xml
1 | <?xml version="1.0" encoding="UTF-8"?> |
Service类:BookServer.java
1 | package com.lzumetal.springboot.demodatabase.service; |
Controller类:BookController.java
1 | package com.lzumetal.springboot.demodatabase.controller; |
SpringBoot项目的启动类:StartupApplication.java
1 | package com.lzumetal.springboot.demodatabase; |
二.测试类
参考官网文档:Testing improvements in Spring Boot 1.4
1.测试Service或者Controller
MainTest.java
1 |
|
官网上的说明:
@RunWith(SpringRunner.class) tells JUnit to run using Spring’s testing support. SpringRunner is the new name for SpringJUnit4ClassRunner, it’s just a bit easier on the eye.
@SpringBootTest is saying “bootstrap with Spring Boot’s support” (e.g. load application.properties and give me all the Spring Boot goodness)
The webEnvironment attribute allows specific “web environments” to be configured for the test. You can start tests with a MOCK servlet environment or with a real HTTP server running on either a RANDOM_PORT or a DEFINED_PORT.
If we want to load a specific configuration, we can use the classes attribute of @SpringBootTest. In this example, we’ve omitted classes which means that the test will first attempt to load @Configuration from any inner-classes, and if that fails, it will search for your primary @SpringBootApplication class.
@RunWith
是junit提供的注解,表示该类是单元测试的执行类- SpringRunner是spring-test提供的测试执行单元类(是Spring单元测试中SpringJUnit4ClassRunner的新名字)
- SpringBootTest 是执行测试程序的引导类。
@ActiveProfiles
是用来指定激活的配置环境。
2.模拟发送REST请求测试
RestTemplate
在java代码里进行REST请求测试,常用的比如Apache的HttpClient,但是spring也提供了一种简单便捷的模板类RestTemplate来进行操作。
RestTemplate是Spring提供的一个web层测试模板类,通过RestTemplate可以很方便地进行web层功能测试。它支持REST风格的URL,而且具有AnnotationMethodHandlerAdapter的数据转换器HttpMessageConverters的装配功能。RestTemplate已默认帮我们完成了一下数据转换器的注册:
- ByteArrayHttpMessageConverter
- StringHttpMessageConverter
- ResourceHttpMessageConverter
- SourceHttpMessageConverter
- XmlAwareFormHttpMessageConverter
在默认情况下,我们可以直接利用以上转换器对响应数据进行转换处理。如StringHttpMessageConverter来处理text/plain
;MappingJackson2HttpMessageConverter来处理application/json
;MappingJackson2XmlHttpMessageConverter来处理application/xml
。
而如果我们像拓展其他的转换器如Jaxb2RootElementHttpMessageConverter或MappingJacksonHttpMessageConverter。我们可以使用setMessageConverters(List<HttpMessageConverter<?>> messageConverters)来注册我们所需的转换器。
1 | RestTemplate restTemplate = new RestTemplate(); |
这个简单的例子展示了如何使用GsonHttpMessageConverter替换掉默认用来处理application/json的MappingJackson2HttpMessageConverter。
RestTemplate默认(即使用无参构造器创建实例)是使用java.net
包中的标准Java类作为底层实现来创建HTTP请求。但是可以调用它的带ClientHttpRequestFactory参数的构造器,使用 Apache 的 HttpComponents 或 Netty 和 OkHttp等其它HTTP请求库。
配置默认实例:
1 |
|
配置定制实例,构造方法中可以传入ClientHttpRequestFactory参数,ClientHttpRequestFactory接口的实现类中存在timeout属性等
1 |
|
TestRestTemplate
TestRestTemplate是SpringBoot提供的一个测试模板类,在SpringBoot你既可以使用RestTemplate,同时也可以使用TestRestTemplate,TestRestTemplate是RestTemplate的一个包装类,而没有继承它,所以不会存在bean注入的问题。如果想在TestRestTemplate中获取,可以调用它的getRestTemplate()
方法。在使用了SpringBootTest
注解的情况下,TestRestTemplate可以直接使用@Autowired
注入。
在下面的示例中主要介绍如何使用TestRestTemplate进行post和get请求测试。如果想使用RestTemplate也差不多是一样的方式。
UrlRequestTest.java
1 | package com.lzumetal.springboot.demodatabase.test; |
官网上的说明:
Note that TestRestTemplate is now available as bean whenever @SpringBootTest is used. It’s pre-configured to resolve relative paths to http://localhost:${local.server.port}. We could have also used the @LocalServerPort annotation to inject the actual port that the server is running on into a test field.
关于webEnvironment,有MOCK、RANDOM_PORT、DEFINED_PORT、NONE四个选项,其中:
- MOCK —提供一个虚拟的Servlet环境,内置的Servlet容器并没有真实的启动
- RANDOM_PORT — 提供一个真实的Servlet环境,也就是说会启动内置容器,然后使用的是随机端口
- DEFINED_PORT — 这个配置也是提供一个真实的Servlet环境,使用的配置文件中配置的端口,如果没有配置,默认是8080
关于SpringBoot的单元测试,可能也还会用到@Before
等其它注解,本文不再全面而深入的研究,仅展示简单示例供使用参考。
本文示例代码已上传到GitHub: https://github.com/liaosilzu2007/spring-boot.git
v1.5.2